import React from "react";
import ProTable from "@ant-design/pro-table";
import { useState, useRef, useImperativeHandle } from 'react';
import { getTaskList } from "../service";
import { Tag, Space, Tabs, message } from 'antd';
import { useRequest, useIntl, FormattedMessage } from 'umi';
import { JsonView, allExpanded, darkStyles, defaultStyles } from 'react-json-view-lite';
import UploadResultFormModal from './UploadResultFormModal'
import 'react-json-view-lite/dist/index.css';
import _ from "lodash";


/**
 * one click copy command
 * @param {*} record data list item 
 */
const copyCommandEvent = (record) => {
  // Step one splicing jobs command, use '\ n' to split
  let commandText = new String("");
  for (let key in record.command.jobs) { commandText += `${record.command.jobs[key].cmd} \n` }

  // Step two create virtually document element input
  let oInput = document.createElement('input')
  oInput.value = commandText;
  document.body.appendChild(oInput)
  oInput.select()
  document.execCommand("Copy")
  oInput.remove()

  // Step three tip copy message
  message.success("command copy success!")
}

const TaskList = React.forwardRef((props, ref) => {
  const actionRef = useRef([]);
  const [listData, SetListData] = useState([])
  const [interval, setInterval] = useState(5000);
  const [currentTabs, setCurrentTabs] = useState({})
  const intl = useIntl();
  let columns = [
    {
      title: <FormattedMessage id="pages.diagnose.diagnosisID" defaultMessage="Diagnosis ID" />,
      dataIndex: "task_id",
      valueType: "textarea",
      width: 150,
      copyable: true,
      sorter: (a, b) => (a.task_id.localeCompare(b.task_id))
    },
    {
      title: <FormattedMessage id="pages.diagnose.creationtime" defaultMessage="Creation time" />,
      dataIndex: "created_at",
      valueType: "dateTime",
      width: 200,
      sorter: (a, b) => (Date.parse(a.created_at) - Date.parse(b.created_at))
    },
    {
      title: <FormattedMessage id="pages.diagnose.state" defaultMessage="State" />,
      dataIndex: 'status',
      width: 150,
      filters: true,
      valueEnum: {
        Ready: { text: <FormattedMessage id="pages.hostTable.status.ready" defaultMessage="ready" />, status: 'Ready' },
        Running: { text: <FormattedMessage id="pages.hostTable.status.running" defaultMessage="Running" />, status: 'Processing' },
        Success: { text: <FormattedMessage id="pages.diagnose.completediagnosis" defaultMessage="Complete diagnosis" />, status: 'Success' },
        Fail: { text: <FormattedMessage id="pages.diagnose.anomaly" defaultMessage="Anomaly" />, status: 'Error' },
      },
      // sorter: (a, b) => (a.status.localeCompare(b.status))
    },
    {
      title: <FormattedMessage id="pages.diagnose.diagnosisParams" defaultMessage="Diagnosis parameters" />,
      dataIndex: 'labels',
      valueType: 'textarea',

      render: (dom, entity, index, action, schema) => {
        // render labels
        let label_elements = [];
        Object.keys(entity.params).forEach((k) => {
          label_elements.push(
            <Tag key={k}>{k}={entity.params[k]}</Tag>
          )
        })
        return <Space size={[0, 'small']} wrap>
          {
            label_elements
          }
        </Space>
      }
    },
    {
      title: <FormattedMessage id="pages.diagnose.operation" defaultMessage="Operation" />,
      dataIndex: "option",
      valueType: "option",
      render: (_, record) => {
        let operations = [];
        if (record.status == "Success") {
          operations.push(
            <a key="showMemInfo" onClick={() => {
              props?.onClick?.(record)
            }}><FormattedMessage id="pages.diagnose.viewdiagnosisresults" defaultMessage="Viewing diagnosis results" /></a>
          )
        }
        else if (record.status == "Running" && props.channel == "offline") {
          operations.push(<UploadResultFormModal record={record} onSuccessCallBack={() => { ref.current?.reload() }} />)
          // one click command copy
          operations.push(
            <a key="copyCommand" onClick={() => { copyCommandEvent(record) }}>
              <FormattedMessage id="page.diagnose.copycommand" defaultMessage="copy command" />
            </a>
          )
        }
        else if (record.status == "Fail") {
          operations.push(
            <a key="showMemError" onClick={() => {
              props?.onError?.(record)
            }}><FormattedMessage id="pages.diagnose.viewerrormessages" defaultMessage="Viewing error messages" /></a>
          )
        } else {
          operations.push(<span><FormattedMessage id="pages.diagnose.nooperation" defaultMessage="No operation is available for the time being" /></span>)
        }
        operations.push(
          <a key="showDetail" onClick={() => {
            window.open("/diagnose/detail/" + record.task_id)
          }}><FormattedMessage id="pages.diagnose.viewdiagnosisdetail" defaultMessage="Viewing diagnosis detail" /></a>
        )
        return operations;
      },
    },
  ];

  return (
    <ProTable
      rowKey="id"
      headerTitle={props.headerTitle || <FormattedMessage id="pages.diagnose.viewdiagnosisrecord" defaultMessage="Diagnosis record viewing" />}
      actionRef={ref}
      columns={columns}
      pagination={{ showSizeChanger: true, pageSizeOptions: [5, 10, 20], defaultPageSize: 5 }}
      search={props.search || false}
      polling={interval}
      tableStyle={{
        wordWrap: 'break-word',
        wordBreak: 'break-word'
      }}
      // rowSelection={{
      //   defaultSelectedRowKeys: [],
      // }}
      params={{ service_name: props.serviceName, channel: props.channel }}
      request={async (params, sort, filter) => {
        if (Object.keys(sort).length != 0) {
          const sort_key = Object.keys(sort)[0];
          const _sort = sort[sort_key] === "ascend" ? sort_key : `-${sort_key}`
          params['ordering'] = _sort
        }
        const result = await getTaskList(params);
        const tabMaps = {};
        result.data.forEach(item => {
          tabMaps[item.task_id] = "params"
        })
        setCurrentTabs(tabMaps)
        SetListData(result.data)
        return result
      }}
      expandable={{
        expandedRowRender: (record) => {
          let items = [
            {
              label: <FormattedMessage id="pages.diagnose.diagnosisParams" defaultMessage="Diagnosis params" />,
              key: "params",
              children: <JsonView data={record.params} shouldExpandNode={allExpanded} style={{
                ...darkStyles,
                container: ""
              }} />
            },
            {
              label: <FormattedMessage id="pages.diagnose.diagnosisCommand" defaultMessage="Diagnosis command" />,
              key: "command",
              children: <JsonView data={record.command} shouldExpandNode={allExpanded} style={{
                ...darkStyles,
                container: ""
              }} />
            }
          ];
          if (record.status == "Success") {
            items.push({
              label: <FormattedMessage id="pages.diagnose.diagnosisresult" defaultMessage="Diagnosis result" />,
              key: "result",
              children: <JsonView data={record.result} shouldExpandNode={allExpanded} style={{
                ...darkStyles,
                container: ""
              }} />
            })
          } else {
            items.push({
              label: <FormattedMessage id="pages.diagnose.diagnosisresult" defaultMessage="Diagnosis result" />,
              key: "result",
              children: <div>
                {record?.err_msg ? record.err_msg : record?.result}
              </div>
            })
          }
          return (
            <>
              <Tabs
                activeKey={currentTabs[record.task_id]}
                // tabPosition='left'
                type='card'
                items={items}
                onChange={(key) => {
                  setCurrentTabs((preState) => {
                    return {
                      ...preState,
                      [record.task_id]: key
                    }
                  });
                }}
              />
            </>
            // <p><JsonView data={record.params} shouldExpandNode={allExpanded} style={{
            //   ...darkStyles,
            //   container: ""
            // }} /></p> 
          )
        },
        showExpandColumn: true,
      }}
    />
  );
});

export default TaskList;
